package com.zhang.common.redis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @Class com.zhang.common.redis.config
 * @Author zhang
 * @Date 2025/9/15 14:47
 * @Description redis配置
 **/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 创建并配置 RedisTemplate Bean
     *
     * @param connectionFactory Redis 连接工厂，由 Spring Boot 自动注入
     * @return 配置好的 RedisTemplate 实例
     *
     * 注意：
     * - 使用 @SuppressWarnings 抑制泛型相关警告
     * - RedisTemplate 的 Key 和 Value 都设置为 Object 类型以支持多种数据类型
     */
    @Bean
    @SuppressWarnings(value = {"unchecked", "rawtypes"})
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建 RedisTemplate 实例
        RedisTemplate<Object, Object> template = new RedisTemplate<>();

        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);

        // 创建 FastJson2JsonRedisSerializer 序列化器，使用 Object.class 支持所有类型
        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);

        // 配置 Jackson 的 ObjectMapper（注意：这里与 FastJSON 混用可能存在问题）
        ObjectMapper mapper = new ObjectMapper();
        // 设置所有字段可见性（包括私有字段）
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 启用默认类型信息，用于多态类型处理
        mapper.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,  // 使用宽松的子类型验证器
                ObjectMapper.DefaultTyping.NON_FINAL,   // 对所有非 final 类型存储类型信息
                JsonTypeInfo.As.PROPERTY                // 类型信息作为属性存储
        );
        // 将 ObjectMapper 设置到序列化器中（注意：FastJson2JsonRedisSerializer 可能不使用此 mapper）
        serializer.setObjectMapper(mapper);

        // 设置 Key 的序列化器为 StringRedisSerializer（字符串序列化）
        template.setKeySerializer(new StringRedisSerializer());
        // 设置 Value 的序列化器为配置好的 FastJson2JsonRedisSerializer
        template.setValueSerializer(serializer);

        // 设置 Hash 结构 Key 的序列化器（同样使用字符串序列化）
        template.setHashKeySerializer(new StringRedisSerializer());
        // 设置 Hash 结构 Value 的序列化器
        template.setHashValueSerializer(serializer);

        // 初始化模板属性
        template.afterPropertiesSet();

        return template;
    }
}